package cn.taobaoke.restful.service;

import cn.taobaoke.restful.domain.AdminEntity;
import cn.taobaoke.restful.domain.AdminRepository;
import cn.taobaoke.restful.exception.TBKException;
import cn.taobaoke.restful.util.MD5Util;
import cn.taobaoke.restful.util.TokenGenerator;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 管理员业务处理层.
 *
 * @author yangzuo
 * @since 2017-03-11
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AdminService {

    /**
     * 新增管理员用户.
     *
     * @param adminEntity
     * @return
     */
    public AdminEntity insertAdminEntity(final AdminEntity adminEntity, final Long domainId) {

        Optional<AdminEntity> optional = adminRepository.findByWeChatOrName(adminEntity.getWeChat(), adminEntity.getName(), domainId);

        if (optional.isPresent()) {
            logger.error("管理员 [{}] 已经存在", adminEntity.getWeChat());
            throw new TBKException("用户名 [" + adminEntity.getWeChat() + "] 已经存在");
        }

        adminEntity.setId(null);
        String md5Pwd = MD5Util.md5(adminEntity.getPassword());
        adminEntity.setPassword(md5Pwd);
        adminEntity.setCreateTime(new Date());
        adminEntity.setToken(TokenGenerator.generateToken(adminEntity.getWeChat()));
        adminEntity.setDomainId(domainId);
        adminEntity.setIsDelete(false);

        AdminEntity result = adminRepository.save(adminEntity);
        logger.info("新增管理员, ID: {}, WeChat: {}", result.getId(), result.getWeChat());

        return filterPassword(result);
    }

    /**
     * 根据管理员ID删除管理员
     *
     * @param adminId
     * @return
     */
    public void deleteAdminEntity(final Long adminId, final Long domainId) {
        Optional<AdminEntity> optional = adminRepository.findById(adminId, domainId);
        if (! optional.isPresent()) {
            logger.error("不存在的管理员ID [{}]", adminId);
            throw new TBKException("不存在的管理员ID [" + adminId + "]");
        }
        AdminEntity entity = optional.get();
        entity.setIsDelete(true);
        entity.setModifiedTime(new Date());
        adminRepository.save(entity);
        logger.warn("删除管理员账号[{}]", adminId);
    }

    /**
     * 更新管理员信息
     *
     * @param admin
     * @return
     */
    public AdminEntity updateAdminEntity(final AdminEntity admin, final Long domainId) {
        Optional<AdminEntity> optional = adminRepository.findById(admin.getId(), domainId);
        if (! optional.isPresent()) {
            logger.error("不存在的管理员ID [{}]", admin.getId());
            throw new TBKException("不存在的管理员ID [" + admin.getId() + "]");
        }

        AdminEntity adminDb = optional.get();
        if (admin.getPassword() != null) {
            String md5Pwd = MD5Util.md5(admin.getPassword());
            adminDb.setPassword(md5Pwd);
        }
        if (admin.getPhone() != null) {
            adminDb.setPhone(admin.getPhone());
        }
        if (admin.getWeChat() != null) {
            adminDb.setWeChat(admin.getWeChat());
        }
        if (admin.getName() != null) {
            adminDb.setName(admin.getName());
        }
        adminDb.setModifiedTime(new Date());

        adminDb = adminRepository.save(adminDb);
        logger.info("修改管理员账号[{}]信息", adminDb.getId());
        return filterPassword(admin);
    }

    /**
     * 获取管理员列表
     *
     * @return
     */
    public List<AdminEntity> getAll(final Long domainId) {
        List<AdminEntity> admins = adminRepository.findAllAdmin(domainId);
        return filterPassword(admins);
    }

    /**
     * @param adminId
     * @return
     */
    public AdminEntity getById(final Long adminId, final Long domainId) {
        Optional<AdminEntity> optional = adminRepository.findById(adminId, domainId);
        if (! optional.isPresent()) {
            logger.error("不存在的管理员ID [{}]", adminId);
            throw new TBKException("不存在的管理员ID [" + adminId + "]");
        }
        return optional.get();
    }

    /**
     * @param weChat
     * @param password
     * @return
     */
    public AdminEntity loginByWeChatAndPassword(final String weChat, final String password, final Long domainId) {
        String md5Pwd = MD5Util.md5(password);
        logger.info("Login by name = [{}], password = [{}]", weChat, md5Pwd);
        Optional<AdminEntity> optional = adminRepository.findByKeywordAndPassword(weChat, md5Pwd, domainId);
        return optional.orElse(null);
    }

    public AdminEntity findByTokenAndDomainId(final String token, final Long domainId) {

        Optional<AdminEntity> optional = adminRepository.findByToken(token, domainId);
//        if (! optional.isPresent()) {
//            logger.error("用户未登陆，请重新登陆");
//            throw new TBKException("用户未登陆，请重新登陆");
//        }

        return optional.orElse(null);
    }

    private List<AdminEntity> filterPassword(final List<AdminEntity> adminList) {
        List<AdminEntity> newAdminList = new ArrayList<>(adminList.size());
        for (AdminEntity entity : adminList) {
            newAdminList.add(filterPassword(entity));
        }
        return newAdminList;
    }

    private AdminEntity filterPassword(AdminEntity adminEntity) {
        AdminEntity dto = new AdminEntity();
        dto.setId(adminEntity.getId());
        dto.setName(adminEntity.getName());
        dto.setWeChat(adminEntity.getWeChat());
        dto.setPhone(adminEntity.getPhone());
        // dto.setToken(adminEntity.getToken());
        dto.setCreateTime(adminEntity.getCreateTime());
        dto.setModifiedTime(adminEntity.getModifiedTime());
        return dto;
    }

    private final @NonNull AdminRepository adminRepository;

    private static Logger logger = LogManager.getLogger(AdminService.class);
}
